package com.beta.resource.utils.shell;

import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;

import org.apache.commons.exec.ProcessDestroyer;
import org.apache.commons.exec.StreamPumper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.beta.resource.utils.onStatusChange;

public class BaseShellStreamPumper extends StreamPumper {
    // private String SYSTEM_FILE_CHARSET_DEFAULT;
    // private String SYSTEM_LANGUAGE_DEFAULT;
    private Charset SYSTEM_CHARSET_DEFAULT;
    public static final int STREAM_MAX_SIZE = 1024;
    private InputStream is;
    private boolean finished;
    private onStatusChange mListener = null;
    private Object mData;
    private ProcessDestroyer mDestoryer;
    
    private Logger log = LoggerFactory.getLogger(getClass());

    public BaseShellStreamPumper(InputStream is, OutputStream os, onStatusChange listener, Object data) {
        this(is, os, false, listener, data);
    }

    public BaseShellStreamPumper(InputStream is, OutputStream os, boolean closeWhenExhausted,
            onStatusChange listener, Object data) {
        super(is, os, closeWhenExhausted, STREAM_MAX_SIZE);
        init();
        this.is = is;
        mListener = listener;
        mData = data;
    }

    public synchronized boolean isFinished() {
        return finished;
    }

    private void init(){
        // SYSTEM_FILE_CHARSET_DEFAULT = System.getProperty("file.encoding");
        // SYSTEM_LANGUAGE_DEFAULT = System.getProperty("user.language");
        SYSTEM_CHARSET_DEFAULT = Charset.defaultCharset();
    }

    public void run() {
        synchronized (this) {
            finished = false;
        }
        byte[] buffer = new byte[STREAM_MAX_SIZE + 1];
        int length = 0;
        try {
            while ((length = is.read(buffer)) != -1) {
                if (mListener != null) {
                    if(!mListener.onLoad(1, buffer, length, mData)){
                        if(mDestoryer != null && mDestoryer instanceof BaseShellProcessDestroyer){
                            ((BaseShellProcessDestroyer)mDestoryer).stop();
                        }
                        break;
                    }
                } else {
                    log.info(new String(buffer, 0, length));
                }
            }
        } catch (final Exception e) {
            e.printStackTrace();
        } finally {
            synchronized (this) {
                finished = true;
                notifyAll();
            }
        }
    }

    public void setDestoryer(ProcessDestroyer destoryer){
        mDestoryer = destoryer;
    }
}
